﻿using System.Globalization;

namespace GoodAdmin.Core;

public class UtilMethod
{
    /// <summary>
    /// 根据Id递归获取下级
    /// </summary>
    /// <typeparam name="T">继承自BaseEntityHasPid的实体类型</typeparam>
    /// <param name="list">指定查找范围</param>
    /// <param name="result">返回结果</param>
    /// <param name="idList">父级组织id列表</param>
    /// <returns></returns>
    public static List<T> GetChild<T>(List<T> list, List<T> result, List<long> idList) where T : BaseTreeEntityId<T>
    {
        if (idList.Count == 0) return result;
        var childs = list.Where(it=>idList.Contains(it.ParentId)).ToList();
        idList = childs.Select(it=>it.Id).ToList();
        result.AddRange(childs);
        return GetChild(list, result, idList);
    }
    
    /// <summary>
    /// 递归获取下级列表
    /// </summary>
    /// <typeparam name="T">实体类型</typeparam>
    /// <typeparam name="TKey"></typeparam>
    /// <param name="list">指定查找范围</param>
    /// <param name="result">返回结果</param>
    /// <param name="keyList">需查询下级信息的Id值</param>
    /// <param name="whereExpression">查询条件</param>
    /// <param name="selectExpression">获取</param>
    /// <returns></returns>
    public List<T> GetChild<T,TKey>(List<T> list, List<T> result, List<TKey> keyList, Func<T, bool> whereExpression,Func<T, TKey> selectExpression) 
    {
        if (keyList.Count == 0) return result;
        var childs = list.Where(whereExpression).ToList();
        keyList = childs.Select(selectExpression).ToList();
        result.AddRange(childs);
        return GetChild(list, result, keyList, whereExpression, selectExpression);
    }

    public static List<T> ConstructTree<T>(List<T> list) where T : BaseTreeEntityId<T>
    {
        if (list.Count == 0) return list;
        //数据范围中可能不包含顶级组织        
        var IdList = list.Select(o => o.Id).ToList();
        //找出当前列表中的最上级
        var topEntity = list.Where(o => !IdList.Contains(o.ParentId)).ToList();
        foreach (var entity in topEntity)
        {
            entity.Children = ConstructTree(list, entity.Id);
        }
        return topEntity;
    }

    private static List<T> ConstructTree<T>(List<T> list, long ParentId) where T : BaseTreeEntityId<T>
    {
        var entitys = list.Where(it => it.ParentId == ParentId).ToList();
        if (entitys.Count == 0) return entitys;
        foreach (var entity in entitys)
        {
            entity.Children = ConstructTree(list, entity.Id);
        }
        return entitys;
    }

    /// <summary>
    /// 将实体字段及对应的注释转换为字典
    /// </summary>
    /// <typeparam name="Entity"></typeparam>
    /// <returns></returns>
    public static Dictionary<string,string> GetEntityMetadataToDic<Entity>()
    {
        var entityMetadataDic = new Dictionary<string, string>();

        var entityType = typeof(Entity);
        var properties = entityType.GetProperties();

        foreach (var property in properties)
        {           
            var displayAttribute = property.GetCustomAttribute<DisplayAttribute>();
            if (displayAttribute == null)
            {
                continue;
            }
            var fieldName = property.Name;
            var comment = displayAttribute.Name;            
            entityMetadataDic.Add(fieldName, comment);
        }

        return entityMetadataDic;
    }

    /// <summary>
    /// 将实体字段及对应的注释转换为List
    /// </summary>
    /// <returns></returns>
    public static List<EntityMetadata> GetEntityMetadataToList<Entity>()
    {
        var entityMetadataList = new List<EntityMetadata>();

        var entityType = typeof(Entity);
        var properties = entityType.GetProperties();

        foreach (var property in properties)
        {            
            var displayAttribute = property.GetCustomAttribute<DisplayAttribute>();
            if (displayAttribute == null)
            {
                continue;
            }
            var metadata = new EntityMetadata
            {
                FieldName = property.Name,
                Comment = displayAttribute.Name//显示名默认为字段名
            };
            entityMetadataList.Add(metadata);
        }
        return entityMetadataList;
    }

    public static List<ExcelColumnModel> GetEntityMetadataToExcelColumnModel<Entity>()
    {
        var entityType = typeof(Entity);
        var properties = entityType.GetProperties();
        var execlConfig = new List<ExcelColumnModel>();
        foreach (var property in properties)
        {            
            var displayAttribute = property.GetCustomAttribute<DisplayAttribute>();
            if (displayAttribute == null)
            {               
                continue;
            }
            var config = new ExcelColumnModel
            {
                Column = property.Name,
                ExcelColumn = displayAttribute.Name //显示名默认为字段名
            };
            execlConfig.Add(config);
        }
        return execlConfig;
    }

    /// <summary>
    /// 日期格式转换
    /// </summary>
    /// <param name="date"></param>
    /// <param name="format"></param>
    /// <param name="inputFormat"></param>
    /// <returns></returns>
    public static string FormatDate(string date, string format, string inputFormat = "yyyy-MM-dd")
    {
        if (DateTime.TryParseExact(date, inputFormat, CultureInfo.InvariantCulture, DateTimeStyles.None, out DateTime parsedDate))
        {
            return parsedDate.ToString(format);
        }
        else
        {
            throw Oops.Bah(date+ " Invalid date format");
        }
    }

    /// <summary>
    /// 转换为日期格式
    /// </summary>
    /// <param name="date"></param>
    /// <param name="inputFormat"></param>
    /// <returns></returns>
    public static DateTime ParseDate(string date, string inputFormat = "yyyy-MM-dd")
    {
        if (DateTime.TryParseExact(date, inputFormat, CultureInfo.InvariantCulture, DateTimeStyles.None, out DateTime parsedDate))
        {
            return parsedDate;
        }
        else
        {
            throw Oops.Bah(date + " Invalid date format");
        }
    }
}